package com.twu.biblioteca.controller;

import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import com.twu.biblioteca.entity.Movie;
import com.twu.biblioteca.enums.MapKey;
import com.twu.biblioteca.enums.Status;
import com.twu.biblioteca.exception.CheckoutFailException;
import com.twu.biblioteca.exception.ReturnFailException;
import com.twu.biblioteca.model.MovieModel;
import com.twu.biblioteca.view.command.Command;

import java.util.List;
import java.util.Map;

@Singleton
public class MovieController extends BaseController {
  private final MovieModel model;

  @Inject
  public MovieController(MovieModel model) {
    this.model = model;
  }

  public void checkout(Movie movie) {
    Map<MapKey, Object> objectMap = null;
    try {
      this.model.checkout(movie);
      objectMap = getObjectMapWithTitle(Command.Type.CheckOutMovie, Status.Success,
          movie.getTitle());
    } catch (CheckoutFailException cfe) {
      System.out.println(cfe.getMessage());
      objectMap = getObjectMap(Command.Type.CheckOutMovie, Status.Failure);
    }
    update(objectMap);
  }



  public void returnMovie(String title) {
    Map<MapKey, Object> objectMap = null;
    try {
      List<Movie> checkoutMovies = model.getCheckoutMovies();
      for (Movie m : checkoutMovies) {
        if (m.getTitle().equals(title)) {
          model.returnMovie(m);
          update(getObjectMapWithTitle(Command.Type.ReturnMovie, Status.Success, m.getTitle()));
          return;
        }
      }
    } catch (ReturnFailException rfe) {
      System.out.println(rfe.getMessage());
    }
    update(getObjectMap(Command.Type.ReturnMovie, Status.Failure));
  }

  private Map<MapKey, Object> getObjectMap(Command.Type type, Status status) {
    Map<MapKey, Object> objectMap = Maps.newHashMap();
    objectMap.put(MapKey.Command, type);
    objectMap.put(MapKey.Status, status);
    objectMap.put(MapKey.Movies, model.getAvailableMovies());
    return objectMap;
  }

  private Map<MapKey, Object> getObjectMapWithTitle(Command.Type type, Status status,
      String itemTitle) {
    Map<MapKey, Object> objectMap = getObjectMap(type, status);
    objectMap.put(MapKey.ITEM_TITLE, itemTitle);
    return objectMap;
  }

  public void movieList() {
    update(getObjectMap(Command.Type.MovieList, Status.Success));
  }
}
